package lvm

import (
	"bufio"
	"context"
	"github.com/sirupsen/logrus"
	"strings"
)

// PVList 物理分区列表
func PVList(ctx context.Context) (map[string]*PhysicalVolume, error) {
	result, err := execCommand(ctx, "pvs",
		"-o", "pv_name,vg_name,pv_size,pv_free,pv_uuid,pv_fmt,pv_allocatable",
		"--noheadings", "--units", "B", "--separator", "||", "-a")
	if err != nil {
		return nil, err
	}
	logrus.Debugf("pvlist: %v", result)
	return processPVList(result)
}

/*
  PV                VG    PSize        PFree        PV UUID                                Fmt  Allocatable
  /dev/mmcblk2boot0                 0B           0B
  /dev/mmcblk2boot1                 0B           0B
  /dev/mmcblk2p1                    0B           0B
  /dev/mmcblk2p2                    0B           0B
  /dev/mmcblk2p3                    0B           0B
  /dev/mmcblk2p4                    0B           0B
  /dev/ram0                         0B           0B
  /dev/ram1                         0B           0B
  /dev/ram2                         0B           0B
  /dev/ram3                         0B           0B
  /dev/sda          npccc 30974935040B 30974935040B wYBajq-U0Fx-VgIe-ybuc-rTfB-KbpN-7mqwvi lvm2 allocatable
*/
func processPVList(result string) (pvs map[string]*PhysicalVolume, err error) {
	scanner := bufio.NewScanner(strings.NewReader(result))
	pvs = make(map[string]*PhysicalVolume)
	for scanner.Scan() {
		l := strings.TrimSpace(scanner.Text())
		sps := strings.Split(l, "||")
		if len(sps) < 7 {
			continue
		}
		pv := &PhysicalVolume{
			Name:   sps[0],
			VGName: sps[1],
			// size_unit: B
			Size:        parseSize(sps[2]),
			FreeSize:    parseSize(sps[3]),
			UUID:        sps[4],
			MetaData:    sps[5],
			Allocatable: sps[6] == "allocatable",
		}
		pvs[pv.Name] = pv
	}
	if len(pvs) == 0 {
		err = ErrEmpty
	}
	return
}
